msg_tool\scripts\will_plus/
ws2_disasm.rs

1use crate::ext::io::*;
2use anyhow::Result;
3use std::any::Any;
4use std::ffi::CString;
5
6pub trait Disasm: Sized {
7    fn disassmble(self) -> Result<(Vec<usize>, Vec<Ws2DString>)>;
8}
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11enum Oper {
12    /// Byte
13    B,
14    /// Word
15    H,
16    /// Int
17    I,
18    /// Address
19    A,
20    /// Float
21    F,
22    /// String
23    S,
24    /// Array of operands (*)
25    ARR,
26}
27use Oper::*;
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq)]
30pub enum StringType {
31    Name,
32    Message,
33    Internal,
34}
35
36#[derive(Debug, Clone)]
37pub struct Ws2DString {
38    pub text: CString,
39    pub offset: usize,
40    pub len: usize,
41    pub typ: StringType,
42}
43
44struct DisasmBase<'a> {
45    reader: MemReaderRef<'a>,
46    opers: &'a [(u8, &'static [Oper])],
47    addresses: Vec<usize>,
48    texts: Vec<Ws2DString>,
49}
50
51impl<'a> DisasmBase<'a> {
52    pub fn new(data: &'a [u8], opers: &'a [(u8, &'static [Oper])]) -> Self {
53        DisasmBase {
54            reader: MemReaderRef::new(data),
55            opers,
56            addresses: Vec::new(),
57            texts: Vec::new(),
58        }
59    }
60
61    fn read_instruction(&mut self) -> Result<(u8, Vec<Box<dyn Any>>)> {
62        let opcode = self.reader.read_u8()?;
63        let opers = self
64            .opers
65            .iter()
66            .find(|&&(op, _)| op == opcode)
67            .ok_or_else(|| anyhow::anyhow!("Unknown opcode: {opcode}"))?;
68        let operands = self.read_operands(opers.1)?;
69        Ok((opcode, operands))
70    }
71
72    fn read_operands(&mut self, opers: &[Oper]) -> Result<Vec<Box<dyn Any>>> {
73        let mut operands = Vec::new();
74        let mut i = 0;
75        let oper_len = opers.len();
76        while i < oper_len {
77            let oper = opers[i];
78            if i < oper_len - 1 && opers[i + 1] == ARR {
79                i += 1;
80                let count = self.reader.read_u8()?;
81                for _ in 0..count {
82                    operands.push(self.read_operand(oper)?);
83                }
84            } else {
85                let operand = self.read_operand(oper)?;
86                operands.push(operand);
87            }
88            i += 1;
89        }
90        Ok(operands)
91    }
92
93    fn read_operand(&mut self, oper: Oper) -> Result<Box<dyn Any>> {
94        match oper {
95            B => {
96                let value = self.reader.read_u8()?;
97                Ok(Box::new(value))
98            }
99            H => {
100                let value = self.reader.read_i16()?;
101                Ok(Box::new(value))
102            }
103            I => {
104                let value = self.reader.read_i32()?;
105                Ok(Box::new(value))
106            }
107            A => {
108                let pos = self.reader.pos;
109                let address = self.reader.read_i32()?;
110                self.addresses.push(pos);
111                Ok(Box::new(address))
112            }
113            F => {
114                let value = self.reader.read_f32()?;
115                Ok(Box::new(value))
116            }
117            S => {
118                let offset = self.reader.pos;
119                let s = self.reader.read_cstring()?;
120                let len = s.as_bytes_with_nul().len();
121                let str = Ws2DString {
122                    text: s,
123                    offset,
124                    len,
125                    typ: StringType::Internal,
126                };
127                Ok(Box::new(str))
128            }
129            _ => {
130                // Handle other operand types as needed
131                Err(anyhow::anyhow!("Unsupported operand type: {:?}", oper))
132            }
133        }
134    }
135
136    fn handle_choice_screen(&mut self, operands: &mut Vec<Box<dyn Any>>) -> Result<()> {
137        if operands.len() < 1 {
138            return Err(anyhow::anyhow!("Invalid operands for choice screen"));
139        }
140        let first = operands.remove(0);
141        let num_choices = first
142            .downcast::<u8>()
143            .map_err(|_| anyhow::anyhow!("Invalid choice count"))?;
144        for _ in 0..*num_choices {
145            let mut opers = self.read_operands(&[H, S, B, H])?;
146            let range = opers.remove(1);
147            let mut range = range
148                .downcast::<Ws2DString>()
149                .map_err(|_| anyhow::anyhow!("Invalid range operand"))?;
150            if range.len > 1 {
151                range.typ = StringType::Message;
152                self.texts.push(*range);
153            }
154            self.read_instruction()?;
155        }
156        Ok(())
157    }
158
159    fn handle_message(&mut self, operands: &mut Vec<Box<dyn Any>>) -> Result<()> {
160        if operands.len() < 3 {
161            return Err(anyhow::anyhow!("Invalid operands for message"));
162        }
163        let range = operands.remove(2);
164        let mut range = range
165            .downcast::<Ws2DString>()
166            .map_err(|_| anyhow::anyhow!("Invalid range operand"))?;
167        if range.len > 1 {
168            range.typ = StringType::Message;
169            self.texts.push(*range);
170        }
171        Ok(())
172    }
173
174    fn handle_op3f(&mut self, operands: &mut Vec<Box<dyn Any>>) -> Result<()> {
175        let mut pre_is_char = false;
176        for oper in operands.iter_mut() {
177            let str = oper
178                .downcast_mut::<Ws2DString>()
179                .ok_or_else(|| anyhow::anyhow!("Invalid string operand"))?;
180            if str.text.as_bytes() == b"char" {
181                pre_is_char = true;
182            } else {
183                if pre_is_char && str.len > 1 {
184                    str.typ = StringType::Message;
185                    pre_is_char = false;
186                }
187            }
188        }
189        Ok(())
190    }
191
192    fn handle_op72(&mut self, operands: &mut Vec<Box<dyn Any>>) -> Result<()> {
193        if operands.len() < 2 {
194            return Err(anyhow::anyhow!("Invalid operands for op72"));
195        }
196        let mes = operands[1]
197            .downcast_mut::<Ws2DString>()
198            .ok_or_else(|| anyhow::anyhow!("Invalid string operand"))?;
199        mes.typ = StringType::Message;
200        Ok(())
201    }
202
203    fn handle_name(&mut self, operands: &mut Vec<Box<dyn Any>>) -> Result<()> {
204        if operands.len() < 1 {
205            return Err(anyhow::anyhow!("Invalid operands for name"));
206        }
207        let name = operands.remove(0);
208        let mut name = name
209            .downcast::<Ws2DString>()
210            .map_err(|_| anyhow::anyhow!("Invalid name operand"))?;
211        if name.len > 1 {
212            name.typ = StringType::Name;
213            self.texts.push(*name);
214        }
215        Ok(())
216    }
217}
218
219impl<'a> Disasm for DisasmBase<'a> {
220    fn disassmble(mut self) -> Result<(Vec<usize>, Vec<Ws2DString>)> {
221        let maxlen = self.reader.data.len() - 8;
222        while self.reader.pos < maxlen {
223            let (opcode, mut operands) = self.read_instruction()?;
224            match opcode {
225                0x0F => self.handle_choice_screen(&mut operands)?,
226                0x14 => self.handle_message(&mut operands)?,
227                0x15 => self.handle_name(&mut operands)?,
228                0x3F => self.handle_op3f(&mut operands)?,
229                0x72 => self.handle_op72(&mut operands)?,
230                _ => {}
231            }
232            for oper in operands {
233                if let Ok(str) = oper.downcast::<Ws2DString>() {
234                    if str.len > 1 {
235                        self.texts.push(*str);
236                    }
237                }
238            }
239        }
240        self.texts.sort_by_key(|s| s.offset);
241        Ok((self.addresses, self.texts))
242    }
243}
244
245const V1_OPS: [(u8, &'static [Oper]); 103] = [
246    (0x00, &[]),
247    (0x01, &[B, H, F, A, A]),
248    (0x02, &[A]),
249    (0x04, &[S]),
250    (0x05, &[]),
251    (0x06, &[A]),
252    (0x07, &[S]),
253    (0x08, &[B]),
254    (0x09, &[B, H, F]),
255    (0x0A, &[H, F]),
256    (0x0B, &[H, B]),
257    (0x0C, &[H, B, H, ARR]),
258    (0x0D, &[H, H, F]),
259    (0x0E, &[H, H, B]),
260    (0x0F, &[B]),
261    (0x11, &[S, F]),
262    (0x12, &[S, B, S]),
263    (0x13, &[]),
264    (0x14, &[I, S, S]),
265    (0x15, &[S]),
266    (0x16, &[B]),
267    (0x17, &[]),
268    (0x18, &[B, S]),
269    (0x19, &[]),
270    (0x1A, &[S]),
271    (0x1B, &[B]),
272    (0x1C, &[S, S, H]),
273    (0x1D, &[H]),
274    (0x1E, &[S, S, F, F, H, H, B]),
275    (0x1F, &[S, F]),
276    (0x20, &[S, F, H]),
277    (0x21, &[S, H, H, H]),
278    (0x22, &[S, B]),
279    (0x28, &[S, S, F, F, H, H, B, H, H, B]),
280    (0x29, &[S, F]),
281    (0x2A, &[S, F, H]),
282    (0x2B, &[S]),
283    (0x2C, &[S]),
284    (0x2D, &[S, B]),
285    (0x2E, &[]),
286    (0x2F, &[S, H, F]),
287    (0x32, &[S]),
288    (0x33, &[S, S, B, B]),
289    (0x34, &[S, S, B, B]),
290    (0x35, &[S, S, B, B, B]),
291    (0x36, &[S, F, F, F, F, F, F, F, B, B]),
292    (0x37, &[S]),
293    (0x38, &[S, B]),
294    (0x39, &[S, B, B, H, ARR]),
295    (0x3A, &[S, B, B]),
296    (0x3B, &[S, S, H, H, H, F, F, F, F, F, F, F, F]),
297    (0x3C, &[S]),
298    (0x3D, &[H]),
299    (0x3E, &[]),
300    (0x3F, &[S, ARR]),
301    (0x40, &[S, S, B]),
302    (0x41, &[S, B]),
303    (0x42, &[S, H]),
304    (0x43, &[S]),
305    (0x44, &[S, S, B]),
306    (0x45, &[S, H, F, F, F, F]),
307    (0x46, &[S, H, B, F, F, F, F]),
308    (0x47, &[S, S, H, B, B, F, F, F, F, F, H, F]),
309    (0x48, &[S, S, H, B, B, S]),
310    (0x49, &[S, S, S]),
311    (0x4A, &[S, S]),
312    (0x4B, &[S, H, H, F, F, F, F]),
313    (0x4C, &[S, H, H, B, F, F, F, F]),
314    (0x4D, &[S, S, H, H, B, B, F, F, F, F, F, H, F]),
315    (0x4E, &[S, S, H, H, B, B, S]),
316    (0x4F, &[S, S, H, S]),
317    (0x50, &[S, S, H]),
318    (0x51, &[S, S, H, F, B]),
319    (0x52, &[S, S, F, H, F, B, S]),
320    (0x53, &[S, S]),
321    (0x54, &[S, S, S]),
322    (0x55, &[S, S]),
323    (
324        0x56,
325        &[
326            S, B, H, F, F, F, F, F, F, F, F, F, F, F, B, F, F, F, F, B, H, S, H, S, S, F,
327        ],
328    ),
329    (0x57, &[S, H]),
330    (0x58, &[S, S]),
331    (0x59, &[S, S, H]),
332    (0x5A, &[S, H, ARR]),
333    (0x5B, &[S, H, B]),
334    (0x5C, &[S]),
335    (0x5D, &[S, S, B]),
336    (0x5E, &[S, F, F]),
337    (0x64, &[B]),
338    (0x65, &[H, B, F, F, B, S]),
339    (0x66, &[S]),
340    (0x67, &[B, B, H, F, F, F, F, F, B]),
341    (0x68, &[B]),
342    (0x6E, &[S, S]),
343    (0x6F, &[S]),
344    (0x70, &[S, H]),
345    (0x71, &[]),
346    (0x72, &[S, S]),
347    (0x73, &[S, S, H]),
348    (0xFA, &[]),
349    (0xFB, &[B]),
350    (0xFC, &[H]),
351    (0xFD, &[]),
352    (0xFE, &[S]),
353    (0xFF, &[]),
354];
355
356const V2_OPS: [(u8, &'static [Oper]); 134] = [
357    (0x00, &[]),
358    (0x01, &[B, H, F, A, A]),
359    (0x02, &[A]),
360    (0x04, &[S]),
361    (0x05, &[]),
362    (0x06, &[A]),
363    (0x07, &[S]),
364    (0x08, &[B]),
365    (0x09, &[B, H, F]),
366    (0x0A, &[H, F]),
367    (0x0B, &[H, B]),
368    (0x0C, &[H, B, H, ARR]),
369    (0x0D, &[H, H, F]),
370    (0x0E, &[H, H, B]),
371    (0x0F, &[B]),
372    (0x11, &[S, F]),
373    (0x12, &[S, B, S]),
374    (0x13, &[]),
375    (0x14, &[I, S, S]),
376    (0x15, &[S]),
377    (0x16, &[B]),
378    (0x17, &[]),
379    (0x18, &[B, S]),
380    (0x19, &[]),
381    (0x1A, &[S]),
382    (0x1B, &[B]),
383    (0x1C, &[S, S, H, B]),
384    (0x1D, &[H]),
385    (0x1E, &[S, S, F, F, H, H, B]),
386    (0x1F, &[S, F]),
387    (0x20, &[S, F, H]),
388    (0x21, &[S, H, H, H]),
389    (0x22, &[S, B]),
390    (0x28, &[S, S, F, F, H, H, B, H, H, B]),
391    (0x29, &[S, F]),
392    (0x2A, &[S, F, H]),
393    (0x2B, &[S]),
394    (0x2C, &[S]),
395    (0x2D, &[S, B]),
396    (0x2E, &[]),
397    (0x2F, &[S, H, F]),
398    (0x32, &[S]),
399    (0x33, &[S, S, B, B]),
400    (0x34, &[S, S, B, B]),
401    (0x35, &[S, S, B, B, B]),
402    (0x36, &[S, F, F, F, F, F, F, F, B, B]),
403    (0x37, &[S]),
404    (0x38, &[S, B]),
405    (0x39, &[S, B, B, H, ARR]),
406    (0x3A, &[S, B, B]),
407    (0x3B, &[S, S, H, H, H, F, F, F, F, F, F, F, F]),
408    (0x3C, &[S]),
409    (0x3D, &[H]),
410    (0x3E, &[]),
411    (0x3F, &[S, ARR]),
412    (0x40, &[S, S, B]),
413    (0x41, &[S, B]),
414    (0x42, &[S, H]),
415    (0x43, &[S]),
416    (0x44, &[S, S, B]),
417    (0x45, &[S, H, F, F, F, F]),
418    (0x46, &[S, H, B, F, F, F, F]),
419    (0x47, &[S, S, H, B, B, F, F, F, F, F, H, F]),
420    (0x48, &[S, S, H, B, B, S]),
421    (0x49, &[S, S, S]),
422    (0x4A, &[S, S]),
423    (0x4B, &[S, H, H, F, F, F, F]),
424    (0x4C, &[S, H, H, B, F, F, F, F]),
425    (0x4D, &[S, S, H, H, B, B, F, F, F, F, F, H, F]),
426    (0x4E, &[S, S, H, H, B, B, S]),
427    (0x4F, &[S, S, H, S]),
428    (0x50, &[S, S, H]),
429    (0x51, &[S, S, H, F, B]),
430    (0x52, &[S, S, F, H, F, B, S]),
431    (0x53, &[S, S]),
432    (0x54, &[S, S, S]),
433    (0x55, &[S, S]),
434    (
435        0x56,
436        &[
437            S, B, H, F, F, F, F, F, F, F, F, F, F, F, B, F, F, F, F, B, H, S, H, S, S, F,
438        ],
439    ),
440    (0x57, &[S, H]),
441    (0x58, &[S, S]),
442    (0x59, &[S, S, H]),
443    (0x5A, &[S, H, ARR]),
444    (0x5B, &[S, H, B]),
445    (0x5C, &[S]),
446    (0x5D, &[S, S, B]),
447    (0x5E, &[S, F, F]),
448    (0x5F, &[S]),
449    (0x60, &[H, H, H, H]),
450    (0x61, &[B, F, F, F, F]),
451    (0x62, &[S]),
452    (0x63, &[S, B]),
453    (0x64, &[B]),
454    (0x65, &[H, B, F, F, B, S]),
455    (0x66, &[S]),
456    (0x67, &[B, B, H, F, F, F, F, F, B]),
457    (0x68, &[B]),
458    (0x69, &[S, B, B, F, F, F, F, F, H, F]),
459    (0x6A, &[S, H, B, B, S]),
460    (0x6E, &[S, S]),
461    (0x6F, &[S]),
462    (0x70, &[S, H]),
463    (0x71, &[]),
464    (0x72, &[S, S]),
465    (0x73, &[S, S, H]),
466    (0x74, &[S, S]),
467    (0x75, &[S, S]),
468    (0x78, &[S, S, B, B]),
469    (0x79, &[S, S, F]),
470    (0x7A, &[S, S, F, B, B, S]),
471    (0x7B, &[S, S]),
472    (0x7C, &[S, S, F]),
473    (0x7D, &[S, F]),
474    (0x7E, &[S]),
475    (0xC8, &[]),
476    (0xC9, &[S, S, H, H, H]),
477    (0xCA, &[S, S]),
478    (0xCB, &[S, B, B]),
479    (0xCC, &[]),
480    (0xCD, &[S, S, S, S, S, F, B]),
481    (0xCE, &[B]),
482    (0xCF, &[S, S, F]),
483    (0xD0, &[S, H]),
484    (0xD1, &[S, H]),
485    (0xD2, &[S]),
486    (0xD3, &[S]),
487    (0xD4, &[S, H, H]),
488    (0xF8, &[]),
489    (0xF9, &[B, S]),
490    (0xFA, &[]),
491    (0xFB, &[B]),
492    (0xFC, &[H]),
493    (0xFD, &[]),
494    (0xFE, &[S]),
495    (0xFF, &[]),
496];
497
498const V3_OPS: [(u8, &'static [Oper]); 165] = [
499    (0x00, &[]),
500    (0x01, &[B, H, F, A, A]),
501    (0x02, &[A]),
502    (0x04, &[S]),
503    (0x05, &[]),
504    (0x06, &[A]),
505    (0x07, &[S]),
506    (0x08, &[B]),
507    (0x09, &[B, H, F]),
508    (0x0A, &[H, F]),
509    (0x0B, &[H, B]),
510    (0x0C, &[H, B, H, ARR]),
511    (0x0D, &[H, H, F]),
512    (0x0E, &[H, H, B]),
513    (0x0F, &[B]),
514    (0x11, &[S, B, F]),
515    (0x12, &[S, B, S]),
516    (0x13, &[]),
517    (0x14, &[I, S, S, B]),
518    (0x15, &[S, B]),
519    (0x16, &[B, B]),
520    (0x17, &[]),
521    (0x18, &[B, S]),
522    (0x19, &[]),
523    (0x1A, &[S]),
524    (0x1B, &[B]),
525    (0x1C, &[S, S, H, B]),
526    (0x1D, &[H]),
527    (0x1E, &[S, S, F, F, H, H, B, F]),
528    (0x1F, &[S, F]),
529    (0x20, &[S, F, H]),
530    (0x21, &[S, H, H, H]),
531    (0x22, &[S, B]),
532    (0x28, &[S, S, F, F, H, H, B, H, H, B, F]),
533    (0x29, &[S, F]),
534    (0x2A, &[S, F, H]),
535    (0x2B, &[S]),
536    (0x2C, &[S]),
537    (0x2D, &[S, B]),
538    (0x2E, &[]),
539    (0x2F, &[S, H, F]),
540    (0x32, &[S]),
541    (0x33, &[S, S, B, B]),
542    (0x34, &[S, S, B, B]),
543    (0x35, &[S, S, B, B, B]),
544    (0x36, &[S, F, F, F, F, F, F, F, B, B]),
545    (0x37, &[S]),
546    (0x38, &[S, B]),
547    (0x39, &[S, B, B, H, ARR]),
548    (0x3A, &[S, B, B]),
549    (0x3B, &[S, S, H, H, H, F, F, F, F, F, F, F, F]),
550    (0x3C, &[S]),
551    (0x3D, &[H]),
552    (0x3E, &[]),
553    (0x3F, &[S, ARR]),
554    (0x40, &[S, S, B]),
555    (0x41, &[S, B]),
556    (0x42, &[S, H]),
557    (0x43, &[S]),
558    (0x44, &[S, S, B]),
559    (0x45, &[S, H, F, F, F, F]),
560    (0x46, &[S, H, B, F, F, F, F]),
561    (0x47, &[S, S, H, B, B, F, F, F, F, F, H, F]),
562    (0x48, &[S, S, H, B, B, S]),
563    (0x49, &[S, S, S]),
564    (0x4A, &[S, S]),
565    (0x4B, &[S, H, H, F, F, F, F]),
566    (0x4C, &[S, H, H, B, F, F, F, F]),
567    (0x4D, &[S, S, H, H, B, B, F, F, F, F, F, H, F]),
568    (0x4E, &[S, S, H, H, B, B, S]),
569    (0x4F, &[S, S, H, S]),
570    (0x50, &[S, S, H]),
571    (0x51, &[S, S, H, F, B]),
572    (0x52, &[S, S, F, H, F, B, S]),
573    (0x53, &[S, S]),
574    (0x54, &[S, S, S]),
575    (0x55, &[S, S]),
576    (
577        0x56,
578        &[
579            S, B, H, F, F, F, F, F, F, F, F, F, F, F, B, F, F, F, F, B, H, S, H, S, S, F,
580        ],
581    ),
582    (0x57, &[S, H]),
583    (0x58, &[S, S]),
584    (0x59, &[S, S, H]),
585    (0x5A, &[S, H, ARR]),
586    (0x5B, &[S, H, B]),
587    (0x5C, &[S]),
588    (0x5D, &[S, S, B]),
589    (0x5E, &[S, F, F]),
590    (0x5F, &[S]),
591    (0x60, &[H, H, H, H]),
592    (0x61, &[B, F, F, F, F]),
593    (0x62, &[S]),
594    (0x63, &[S, B]),
595    (0x64, &[B]),
596    (0x65, &[H, B, F, F, B, S]),
597    (0x66, &[S]),
598    (0x67, &[B, B, H, F, F, F, F, F, B]),
599    (0x68, &[B]),
600    (0x69, &[S, B, B, F, F, F, F, F, H, F]),
601    (0x6A, &[S, H, B, B, S]),
602    (0x6B, &[S, S]),
603    (0x6C, &[S, F, F]),
604    (0x6E, &[S, S]),
605    (0x6F, &[S]),
606    (0x70, &[S, H]),
607    (0x71, &[]),
608    (0x72, &[S, S]),
609    (0x73, &[S, S, H]),
610    (0x74, &[S, S]),
611    (0x75, &[S, S]),
612    (0x78, &[S, S, B, B, B]),
613    (0x79, &[S, S, F]),
614    (0x7A, &[S, S, F, B, B, S]),
615    (0x7B, &[S, S]),
616    (0x7C, &[S, S, F]),
617    (0x7D, &[S, F]),
618    (0x7E, &[S]),
619    (0x7F, &[S, F, F, F, F, F]),
620    (0x80, &[S]),
621    (0x81, &[S, B, S, F, F, B]),
622    (0x82, &[S, S, F]),
623    (0x83, &[S, S, F, F]),
624    (0x84, &[S, S, S, F, H, F]),
625    (0x85, &[S, S, B, F]),
626    (0x86, &[S, F, F, F]),
627    (0x87, &[S, F]),
628    (0x88, &[S, S, S, F, H, F]),
629    (0x8C, &[S, S, S, B, B]),
630    (0x8D, &[I, S, S, B, B, S]),
631    (0x8E, &[I, S, S, B, B, S]),
632    (0x8F, &[S, S]),
633    (0x90, &[S]),
634    (0x96, &[H, F, F, F, F]),
635    (0x97, &[H, B, F, F, F, F]),
636    (0x98, &[S, H, B, B, F, F, F, F, F, H, F]),
637    (0x99, &[S, H, B, B, S]),
638    (0x9A, &[]),
639    (0x9B, &[S]),
640    (0x9C, &[S, S]),
641    (0x9D, &[S]),
642    (0x9E, &[S, B]),
643    (0x9F, &[S, B]),
644    (0xC8, &[]),
645    (0xC9, &[S, S, H, H, H, H]),
646    (0xCA, &[S, S]),
647    (0xCB, &[S, B, B]),
648    (0xCC, &[]),
649    (0xCD, &[S, S, S, S, S, F, B]),
650    (0xCE, &[B]),
651    (0xCF, &[S, S, F]),
652    (0xD0, &[S, H]),
653    (0xD1, &[S, H]),
654    (0xD2, &[S]),
655    (0xD3, &[S]),
656    (0xD4, &[S, H, H]),
657    (0xE6, &[I, I]),
658    (0xE7, &[]),
659    (0xE8, &[]),
660    (0xF0, &[B]),
661    (0xF8, &[]),
662    (0xF9, &[B, S]),
663    (0xFA, &[]),
664    (0xFB, &[B]),
665    (0xFC, &[H]),
666    (0xFD, &[]),
667    (0xFE, &[S]),
668    (0xFF, &[]),
669];
670
671const OPS: [&[(u8, &'static [Oper])]; 3] = [&V1_OPS, &V2_OPS, &V3_OPS];
672
673pub fn disassmble(data: &[u8]) -> Result<(Vec<usize>, Vec<Ws2DString>)> {
674    for op in &OPS {
675        let disasm = DisasmBase::new(data, op);
676        match disasm.disassmble() {
677            Ok(result) => return Ok(result),
678            Err(_) => continue, // Try the next version if this one fails
679        }
680    }
681    Err(anyhow::anyhow!(
682        "Failed to disassemble the data with all known versions"
683    ))
684}